package com.mes.basicdata.domain;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.hibernate.annotations.BatchSize;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.ForeignKey;
import org.hibernate.annotations.Formula;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.JoinColumnOrFormula;
import org.hibernate.annotations.JoinColumnsOrFormulas;
import org.hibernate.annotations.JoinFormula;
import org.hibernate.annotations.OrderBy;
import org.springframework.context.annotation.Lazy;

import com.mes.common.domain.BasicModel;


/**
 * <p>
 * 工艺对象
 * </p>
 * 
 * <p>
 * Created on 2017-03-16
 * </p>
 * 
 * @author lcs
 * 
 */
@Entity()
@org.hibernate.annotations.Entity(dynamicInsert=true,dynamicUpdate=true)
@Table(name = "B_ROUTINE_HEADER")
@BatchSize(size=20)
@Lazy(value=true)
@Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Routing extends BasicModel  {
	public final static String  ROUTINGTYPE_PLAN="plan";//计划工艺
	public final static String  ROUTING_NAME_DEFAULT_PLAN="缺省计划工艺";//计划工艺
	
	// 工艺编号
	@Id
	@GenericGenerator(name = "routingUid", strategy = "assigned")
	@Column(name="ROUTING",unique=true)
	private String routingUid;
	
	// 工艺号,业务上的
	@Column(name="ROUTINGID")
	private String routingId;

	// 是否有效
	@Column(name="EFFECTIVE",precision=2,scale=0)
	private Boolean isEffective;
	
	// 零件编号
	@Column(name="PART_NUMBER")
	private String partUid;
	// 零件
	//many-to-one
	@ForeignKey(name="null")
	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name="PART_NUMBER",insertable=false,updatable=false)
	private Part part;
	
	// 工艺名称
	@Column(name="ROUTING_NAME")
	private String routingName;
	
	// 工艺版本号
	@Column(name="VERSIONID")
	private String versionId;

	
	
	@Column(name="CHECKER")
	private String checkerUid;
	// 检查者
	//many-to-one
	@ForeignKey(name="null")
	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name="CHECKER",insertable=false,updatable=false)
	private Employee checker;
	
	// 审核者
	//many-to-one
	@ForeignKey(name="null")
	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name="AUDITOR",insertable=false,updatable=false)
	private Employee auditor;
	// 批准者
	//many-to-one
	@ForeignKey(name="null")
	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name="APPROVER",insertable=false,updatable=false)
	private Employee approver;
	// 工时系数
	@Column(name="WORKTIME_RATION")
	private Integer workTimeRation;
	// 是否关键
	@Column(name="ISCRITICAL", precision=2, scale=0)
	private Integer isCritical;
	// 是否默认工艺
	@Column(name="USEEFFECTIVE")
	private Boolean isDefault;
	// 主制车间
	//many-to-one
	@ForeignKey(name="null")
	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name="MASTERSHOP",insertable=false,updatable=false)
	private Dept masterShop;
	// 主制车间
	@Column(name="MASTERSHOP")
	private String masterShopUid;
	// private Dept masterShop;

	// 工艺类型
	@Column(name="ROUTING_TYPE")
	private String routingType;
	@ForeignKey(name="null")
//	@NotFound(action=NotFoundAction.IGNORE)
	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumnsOrFormulas(value={
			@JoinColumnOrFormula(column=@JoinColumn(name="ROUTING_TYPE",referencedColumnName="ID",nullable=true,insertable=false,updatable=false)),
			@JoinColumnOrFormula(formula=@JoinFormula(value="'routing_type'", referencedColumnName="TYPESNAME"))
	})
	private TypesData routingTypeDesc;//routing_type
	
	// 该工艺作为子工艺对应的父工艺中的某个工序，如热处理工序
	@Column(name="OPUID")
	private String parentOperationUid;
	//many-to-one
	@ForeignKey(name="null")
	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name="OPUID",insertable=false,updatable=false)
	private Operation parentOperation;
	
	//类型
	@Column(name="PRODUCT_PHASE")
	private String productPhase;
	
	@ForeignKey(name="null")
//	@NotFound(action=NotFoundAction.IGNORE)
	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumnsOrFormulas(value={
			@JoinColumnOrFormula(column=@JoinColumn(name="PRODUCT_PHASE",referencedColumnName="ID",nullable=true,insertable=false,updatable=false)),
			@JoinColumnOrFormula(formula=@JoinFormula(value="'PRODUCT_PHASE'", referencedColumnName="TYPESNAME"))
	})
	private TypesData productPhaseDesc;//routing_type
	
	@Column(name="CHECKTIME")
	private Date checkTime;
	
	@Column(name="APPROVETIME")
	private Date approveTime;
	
	//many-to-one
	//主管工艺
	@ForeignKey(name="null")
	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name="ROUTINEMANAGER",insertable=false,updatable=false)
	private Employee routingManager;
	@Column(name="ROUTINEMANAGER")
	private String routingManagerUid;
	
	private Integer changeState;
	
	@Column(name="PARENTROUTING")
	private String parentRoutingUid;
	//many-to-one
	@ForeignKey(name="null")
	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name="PARENTROUTING",insertable=false,updatable=false)
	private Routing parentRouting;
	
//	@Transient //此属性加上，hibernate就会忽略routingOperations属性，导致获取的值为null
	@OneToMany(fetch=FetchType.LAZY, mappedBy = "routing")
	@OrderBy(clause="OPERATION_ID asc")
	private Set<RoutingOperation> routingOperations;
	
	@Column(name="TOTALWORK")
	private Float totalWork;
	
	/*
	 * 工艺关联的非结构化文档数量
	 */
	//@Formula("(select count(*) from f_file_field fff where fff.fielduid=ROUTING  and fff.fieldType='ROUTING_FILE')")
	@Transient
	private Integer fileCount;

	// 多个工序连接，还没有加进去，因为目前的制造经理是不支持多工艺路线的。
	private transient Set<OperationLink> operationLinks = new HashSet<OperationLink>(0);
	// 多个工序
	// modify by lhy Set 改为 List
	private transient List<Operation> operations = new ArrayList<Operation>(0);
	// 多个routingoper
	
	// 分工
	@Column(name="OPTYPE")
	private Integer opType;
	
	// 架次号
	@Column(name="CONTIGNATION_NUMBER")
	private String contignationNumber;


	@Override
	public String getUuid() {
		// TODO Auto-generated method stub
		return this.getRoutingUid();
	}
	@Override
	public void setUuid(String uuid) {
		// TODO Auto-generated method stub
		this.setRoutingUid(uuid);
	}

	public String getRoutingUid() {
		return routingUid;
	}
	public void setRoutingUid(String routingUid) {
		this.routingUid = routingUid;
	}
	

	/*
	 * 这种获取方法非常好，但还未采用网络工艺路线
	 */
	public List<Operation> getOperations() {
//		if (operations.size() == 0) {// 假如没有Operation，首先进行查询
//			Set<RoutingOperation> ros = this.getRoutingOperations();
//			List<Operation> temp = new ArrayList<Operation>();
//			Iterator iter = ros.iterator();
//			while (iter.hasNext()) {
//				RoutingOperation routingOperation = (RoutingOperation) iter.next();
//				try {
//					Operation operation = routingOperation.getOperation();
////					operation.setOperationId(routingOperation.getOperationId());
//					temp.add(operation);
//				} catch (RuntimeException e) {
//					// TODO Auto-generated catch block  
//					e.printStackTrace();  
//				}
//			}
//			operations = temp;
//		}
		return operations;
	}
	
	public void setOperations(List<Operation> operations) {
		this.operations = operations;
	}

//	public String getRoutingUid() {
//		return routingUid;
//	}
//
//	public void setRoutingUid(String routingUid) {
//		this.routingUid = routingUid;
//	}

	public String getRoutingId() {
		return routingId;
	}

	public void setRoutingId(String routingId) {
		this.routingId = routingId;
	}

	public String getPartUid() {
		return partUid;
	}

	public void setPartUid(String partUid) {
		this.partUid = partUid;
	}

	public Part getPart() {
		return part;
	}

	public void setPart(Part part) {
		this.part = part;
	}

	public String getRoutingName() {
		return routingName;
	}

	public void setRoutingName(String routingName) {
		this.routingName = routingName;
	}

	public String getVersionId() {
		return versionId;
	}

	public void setVersionId(String versionId) {
		this.versionId = versionId;
	}
	
	public Boolean getIsEffective() {
		return isEffective;
	}
	public void setIsEffective(Boolean isEffective) {
		this.isEffective = isEffective;
	}

	public Employee getChecker() {
		return checker;
	}

	public void setChecker(Employee checker) {
		this.checker = checker;
	}

	public Employee getAuditor() {
		return auditor;
	}

	public void setAuditor(Employee auditor) {
		this.auditor = auditor;
	}

	public Employee getApprover() {
		return approver;
	}

	public void setApprover(Employee approver) {
		this.approver = approver;
	}

	public Integer getWorkTimeRation() {
		return workTimeRation;
	}

	public void setWorkTimeRation(Integer workTimeRation) {
		this.workTimeRation = workTimeRation;
	}

	public Integer getIsCritical() {
		return isCritical;
	}

	public void setIsCritical(Integer isCritical) {
		this.isCritical = isCritical;
	}

	/*public Integer getUseEffective() {
		return useEffective;
	}

	public void setUseEffective(Integer useEffective) {
		this.useEffective = useEffective;
	}*/
	

	public Dept getMasterShop() {
		return masterShop;
	}

	public Boolean getIsDefault() {
		return isDefault;
	}
	public void setIsDefault(Boolean isDefault) {
		this.isDefault = isDefault;
	}
	public void setMasterShop(Dept masterShop) {
		this.masterShop = masterShop;
	}


	public String getRoutingType() {
		return routingType;
	}

	public void setRoutingType(String routingType) {
		this.routingType = routingType;
	}

	public String getProductPhase() {
		return productPhase;
	}

	public void setProductPhase(String productPhase) {
		this.productPhase = productPhase;
	}

	public Date getCheckTime() {
		return checkTime;
	}

	public void setCheckTime(Date checkTime) {
		this.checkTime = checkTime;
	}

	public Date getApproveTime() {
		return approveTime;
	}

	public void setApproveTime(Date approveTime) {
		this.approveTime = approveTime;
	}



	public Set<OperationLink> getOperationLinks() {
		return operationLinks;
	}

	public void setOperationLinks(Set<OperationLink> operationLinks) {
		this.operationLinks = operationLinks;
	}

	public String getCheckerUid() {
		return checkerUid;
	}

	public void setCheckerUid(String checkerUid) {
		this.checkerUid = checkerUid;
	}



	public String getParentRoutingUid() {
		return parentRoutingUid;
	}

	public void setParentRoutingUid(String parentRoutingUid) {
		this.parentRoutingUid = parentRoutingUid;
	}

	public Routing getParentRouting() {
		return parentRouting;
	}

	public void setParentRouting(Routing parentRouting) {
		this.parentRouting = parentRouting;
	}

	public Float getTotalWork() {
		return totalWork;
	}

	public void setTotalWork(Float totalWork) {
		this.totalWork = totalWork;
	}

	public Integer getFileCount() {
		return fileCount;
	}

	public void setFileCount(Integer fileCount) {
		this.fileCount = fileCount;
	}

	public Integer getChangeState() {
		return changeState;
	}

	public void setChangeState(Integer changeState) {
		this.changeState = changeState;
	}

	public String getMasterShopUid() {
		return masterShopUid;
	}

	public void setMasterShopUid(String masterShopUid) {
		this.masterShopUid = masterShopUid;
	}

	public Employee getRoutingManager() {
		return routingManager;
	}

	public String getRoutingManagerUid() {
		return routingManagerUid;
	}

	public void setRoutingManager(Employee routingManager) {
		this.routingManager = routingManager;
	}

	public void setRoutingManagerUid(String routingManagerUid) {
		this.routingManagerUid = routingManagerUid;
	}

    public Set<RoutingOperation> getRoutingOperations() {
		return routingOperations;
	}
	public void setRoutingOperations(Set<RoutingOperation> routingOperations) {
		this.routingOperations=routingOperations;
	}
	
	public Integer getOpType() {
		return opType;
	}
	
	public void setOpType(Integer opType) {
		this.opType = opType;
	}
	
	public String getContignationNumber() {
		return contignationNumber;
	}
	
	public void setContignationNumber(String contignationNumber) {
		this.contignationNumber = contignationNumber;
	}
	
	public String getParentOperationUid() {
		return parentOperationUid;
	}

	public void setParentOperationUid(String parentOperationUid) {
		this.parentOperationUid = parentOperationUid;
	}
	
	public Operation getParentOperation() {
		return parentOperation;
	}
	
	public void setParentOperation(Operation parentOperation) {
		this.parentOperation = parentOperation;
	}
	
}